//@author A0083782W

#include "CallDueEvents.h"

CallDueEvents::CallDueEvents() {
	_dueQueue.clear();
	_dueQueue.shrink_to_fit();
	_readStorage = (EventVector const *) EventStorage::get().getEventVectorPtr();
	_availableIndex.clear();
	_availableIndex.shrink_to_fit();
	_currentDay = EventStorage::get().getStartDay();
	if (_currentDay.isEmpty()) {
		CurrentTime nowClock;
		_currentDay = nowClock;
	}
}

bool CallDueEvents::notEmpty() {
	return !_dueQueue.empty();
}

void CallDueEvents::operator = (const vector<pos_int>& rightOperand) {
	_dueQueue.clear();
	_dueQueue.shrink_to_fit();
	_availableIndex.clear();
	_availableIndex.shrink_to_fit();
	_availableIndex = rightOperand;
}

void CallDueEvents::trigger() {
	CurrentTime nowClock;
	Time currentClock;
	currentClock = nowClock;
	for (auto i:_availableIndex) {
		if ((*_readStorage)[i].getStartTime() <= currentClock) {
			if ((*_readStorage)[i].isDone() == false) {
				if ((*_readStorage)[i].getRepeatRule().frequency != RepeatFrequency::NO_REPEAT) {
					if ((*_readStorage)[i].isReminded() == false) {
						_dueQueue.push_back (i);
					}
				}
				else {
					if((*_readStorage)[i].isMissed() == false && 
						(*_readStorage)[i].isReminded() == false) { 
						_dueQueue.push_back (i);
					}
				}
			}
		}
	}
	for (pos_int i = 0; i < _readStorage->size();i++) {
		if ((*_readStorage)[i].getRemindTime().isEmpty() ==  false &&
			(*_readStorage)[i].getRemindTime().isCompletedDate() == true &&
			(*_readStorage)[i].getRemindTime() <= currentClock &&
			(*_readStorage)[i].isReminded() == false) {
			_dueQueue.push_back(i);
		}
	}

	currentClock--;
	if (currentClock &= _currentDay) {
		_currentDay = nowClock;
		Operations::get().updateRepeat();
	}
}

CallDueEvents& CallDueEvents::get() {
	static CallDueEvents newInstance;
	return newInstance;
}

pos_int CallDueEvents::deQueue() {
	pos_int result = _dueQueue[0];
	_dueQueue.erase (_dueQueue.begin());
	_dueQueue.shrink_to_fit();
	return result;
}